home *** CD-ROM | disk | FTP | other *** search
- // =======================================================================
-
- /* SetFont 2.5 - by Dave Haynie
-
- BIX: hazy
- Usenet: {uunet|rutgers}!cbmvax!daveh
- PLINK: D-Dave H
- Drink: Guinness
-
- BUSINESS:
-
- This program is complete, real, and true public domain software.
- Do with it what you will as long as you don't remove my name from it.
- Feel free to enhance this as you see fit. I may eventually make one
- that's better....
-
- ABOUT IT:
-
- SetFont V2.5 cleans up all known bugs in SetFont V2.0, and it's
- the first C++ version. The code is GREATLY cleaned up and simplified
- from SetFont V2.0. I no longer free any fonts that were previously
- set. V2.0 did too much freeing, but even with that, it is possible
- that another program could get a pointer to the font or font descriptor
- in a window or screen and choke if that's freed. That may not be good
- behavior, but this way's safer. A future version will probably track
- fonts opened and closed by SetFont itsself so that it can reclaim some
- of it's resources and still be reasonably safe. Right now I have no
- way of knowing if the font or descriptor I see is even really owned by
- SetFont.
-
- CONFLICTS:
-
- There are a few potential problems the general notion of SetFont in
- the Amiga system. First of all, many programs are written to support only
- the topaz 8 (80 column) font (sloppy, I know, but that's life). If you're
- a 60 column user, you've probably experienced this before. It's not a
- problem with the Amiga as a whole, since most of the system will adjust
- itself. But it may be a problem with programs that have a fixed idea of
- what a font should look like. Most 80 column fonts work with most
- applications, and an 80 column 8x8 font will work just about everywhere.
- Some programs, like CLI for instance, have trouble with proportionally-
- spaced fonts. The best thing to do is try out the font you like. One
- final problem is that some applications ask the WorkBench screen to close
- when they start up. It'll close if there's nothing else open on it, but
- when it re-opens, it'll restart with the Preferences-selected font, not
- the SetFont selected font. Of course, preferences doesn't support
- arbitrary fonts (which is why this program is even necessary). Oh well,
- maybe day.
- */
-
- #include <exec/types.h>
- #include <exec/io.h>
- #include <exec/ports.h>
- #include <exec/memory.h>
- #include <graphics/gfxbase.h>
- #include <graphics/text.h>
- #include <graphics/rastport.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <intuition/intuition.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- // =========================================================================
-
- // Miscellaneous stuff.
-
- extern TextFont *OpenDiskFont(const TextAttr *);
-
- inline BPTR CADDR(APTR cptr) { return BPTR(ULONG(cptr) >> 2); }
-
- inline void fail(char *a, char *b = NULL) { printf(a,b); exit(10); }
-
- inline MsgPort *contask(MsgPort *port) {
- return (MsgPort *) ((port->mp_SigTask->ln_Type == NT_PROCESS)
- ? ((Process *)port->mp_SigTask)->pr_ConsoleTask
- : NULL);
- }
-
- // =========================================================================
-
- // This is the "smart" font class. SmartFont items stay around after the
- // program exits if they appear to have been used.
-
- class SmartFont {
- private:
- static BOOL aok; // Font checks out
- TextAttr sfattr; // Font descriptor
-
- public:
- SmartFont(char *n, UWORD s);
-
- TextFont *font() {
- TextFont *f = OpenDiskFont(&sfattr);
-
- if (!f) f = OpenFont(&sfattr);
- if (!f) fail("Font \"%s\" not found\n",sfattr.ta_Name);
- return f;
- }
- TextAttr *attr() {
- TextAttr *a = (TextAttr *)AllocMem(sizeof(TextAttr),MEMF_PUBLIC|MEMF_CLEAR);
- a->ta_Name = (char *)AllocMem(strlen(sfattr.ta_Name)+1,MEMF_PUBLIC|MEMF_CLEAR);
- strcpy(a->ta_Name,sfattr.ta_Name);
- a->ta_YSize = sfattr.ta_YSize;
- return a;
- }
- char *name() { return sfattr.ta_Name; }
- UWORD size() { return sfattr.ta_YSize; }
- };
-
- SmartFont::SmartFont(char *n, UWORD s = 8) {
- strcat(strcpy(sfattr.ta_Name = new char[strlen(n)+6],n),".font");
- sfattr.ta_YSize = (s>2)?s:8;
- sfattr.ta_Style = sfattr.ta_Flags = 0;
-
- if (!aok) {
- TextFont *f = font();
- CloseFont(f);
- aok = TRUE;
- }
- }
-
- // =========================================================================
-
- // These classes manage the places that fonts are hidden.
-
- // This is the basic place node
-
- class PlaceNode : public Node {
- private:
- static Window *pwin;
- static Screen *pscr;
-
- public:
- PlaceNode();
- PlaceNode *next() { return (PlaceNode *)Node::next(); }
-
- void testwindow() { if (!pwin) fail("Window not found\n"); }
- void testscreen() { if (!pscr) fail("Screen not found\n"); }
-
- Window *window() { return pwin; }
- Screen *screen() { return pscr; }
-
- virtual void set(SmartFont *f) {
- testwindow();
- SetFont(window()->graphic(),f->font());
- printf("\033c"); // Re-init window's conunit
- (void)flushall();
- }
- };
-
- // Initialize the static stuff, once.
-
- PlaceNode::PlaceNode() {
- if (pwin) return;
-
- StandardPacket *packet = new StandardPacket;
- InfoData *info = new InfoData;
- MsgPort *port = new StdPort;
-
- // Find the window
- if (contask(port)) {
- packet->sendio(contask(port),port,ACTION_DISK_INFO,CADDR(info));
- (void)port->wait();
- pwin = (Window *)info->id_VolumeNode;
- } else
- pwin = NULL;
- delete port;
- delete info;
- delete packet;
-
- // Find the screen
- pscr = (pwin) ? pwin->screen() : NULL;
- }
-
- // These are the derived special nodes, one for each "place".
-
- #define WindowNode PlaceNode
-
- class ScreenNode : public PlaceNode {
- public:
- void set(SmartFont *f) {
- testscreen();
- if (strcmp(screen()->Font->ta_Name,f->name()) == 0)
- screen()->Font->ta_YSize = f->size();
- else
- screen()->Font = f->attr();
- }
- };
-
- class TitleNode : public PlaceNode {
- public:
- void set(SmartFont *f) {
- testscreen();
- SetFont(screen()->graphic(),f->font());
- }
- };
-
- class BarNode : public PlaceNode {
- public:
- void set(SmartFont *f) {
- testscreen();
- SetFont(screen()->BarLayer->rp,f->font());
- }
- };
-
- // This is the place list, which links a number of place nodes, and also
- // manages to go work like finding windows, etc.
-
- class PlaceList : public List {
- public:
- PlaceList(int argc, char **argv);
- PlaceNode *first() { return (PlaceNode *)List::first(); }
- };
-
- // The PlaceList constructor does a great deal of the work. It looks up
- // the window data, then parses the command line to build the place
- // list.
-
- PlaceList::PlaceList(int argc, char **argv) {
- // Parse our input arguments
- for (short i = 0; i < argc; ++i)
- switch (toupper(argv[i][0])) {
- case 'B': add(new BarNode); break;
- case 'S': add(new ScreenNode); break;
- case 'T': add(new TitleNode); break;
- case 'W': add(new WindowNode); break;
- default : break;
- }
- if (is_empty()) {
- add(new BarNode);
- add(new ScreenNode);
- add(new TitleNode);
- add(new WindowNode);
- }
- }
-
- // =========================================================================
-
- // Prints help notice
-
- void PrintNotice() {
- printf("SetFont 2.5 by Dave Haynie\n\n");
- printf("Usage: SetFont [fontname [point [place]]]\n");
- printf(" where:\n");
- printf(" \2331mfontname\2330m is the font's name (e.g. \"topaz\")\n");
- printf(" \2331mpoint\2330m is the point size (default is 8)\n");
- printf(" \2331mplace\2330m pick the place, one or more of:\n");
- printf(" \2331mBAR\2330m set the barlayer font only\n");
- printf(" \2331mSCREEN\2330m set the screen font only\n");
- printf(" \2331mTITLES\2330m set the screen titles only\n");
- printf(" \2331mWINDOW\2330m set the window's font only\n\n");
- printf("If no \2331mplace\2330m switch is given, everything is set.\n\n");
- exit(0);
- }
-
- // The main function
-
- void main(int argc, char *argv[]) {
- // Automatic help command
- if (argc < 2 || argv[1][0] == '?') PrintNotice();
-
- // Process the command-line arguments, AmigaDOS style.
- PlaceList *plist = new PlaceList(argc-2,&argv[3]);
-
- // Get the font if it's there.
- SmartFont *font = new SmartFont(argv[1],atoi(argv[2]));
-
- // Here we apply all the requested changes.
- for (PlaceNode *n = plist->first(); n->next(); n = n->next()) n->set(font);
-
- // And we're done!
- exit(0);
- }
-